/**
 * ReportGear(2011)
 */
package net.abbp.report.model.cell.style;

import java.awt.Color;
import java.util.Map;
import java.util.WeakHashMap;

/**
 * 单元格边框样式
 * 
 * @version 1.0 2011-3-10
 * @author <a herf="lexloo@gmail.com">lexloo</a>
 * @since Report 1.0
 */
public class BorderStyle {
    // 边框样式缓存
    private static Map<BorderStyle, BorderStyle> cachedBorderStyle = new WeakHashMap<BorderStyle, BorderStyle>();
    /**
     * 默认单元格边框样式
     */
    public static BorderStyle DEFAULT_STYLE = BorderStyle.getInstance();

    /**
     * 无边框
     */
    public static final int NO_BORDERS = 0;
    /**
     * 外部边框
     */
    public static final int EXTERNAL_BORDERS = 1;
    /**
     * 内部线
     */
    public static final int INSIDE_BORDERS = 2;
    /**
     * 上
     */
    public static final int TOP_BORDER = 3;
    /**
     * 左
     */
    public static final int LEFT_BORDER = 4;
    /**
     * 下
     */
    public static final int BOTTOM_BORDER = 5;
    /**
     * 右
     */
    public static final int RIGHT_BORDER = 6;
    /**
     * 垂直线
     */
    public static final int VERTICAL_BORDER = 7;
    /**
     * 水平线
     */
    public static final int HORIZONTAL_BORDER = 8;

    private Color bottomColor = Color.BLACK;
    private int bottomStyle = 1;
    private Color horizentalColor = Color.BLACK;
    private int horizentalStyle = 1;
    private Color leftColor = Color.BLACK;
    private int leftStyle = 1;
    private Color rightColor = Color.BLACK;
    private int rightStyle = 1;
    private Color topColor = Color.BLACK;
    private int topStyle = 1;
    private Color verticalColor = Color.BLACK;
    private int verticalStyle = 1;

    /**
     * @return 获取单元格边框样式实例
     */
    public static BorderStyle getInstance() {
        return BorderStyle.getInstance(1,
                                       Color.BLACK,
                                       1,
                                       Color.BLACK,
                                       1,
                                       Color.BLACK,
                                       1,
                                       Color.BLACK,
                                       1,
                                       Color.BLACK,
                                       1,
                                       Color.BLACK);
    }

    /**
     * 获取单元格边框样式实例
     * 
     * @param topStyle 上边框类型
     * @param topColor 上边框颜色
     * @param leftStyle 左边框类型
     * @param leftColor 左边框颜色
     * @param bottomStyle 下边框类型
     * @param bottomColor 下边框颜色
     * @param rightStyle 右边框类型
     * @param rightColor 右边框颜色
     * @param horizentalStyle 水平线类型
     * @param horizentalColor 水平线颜色
     * @param verticalStyle 垂直线类型
     * @param verticalColor 垂直线颜色
     * @return 单元格边框样式实例
     */
    public static BorderStyle getInstance(int topStyle,
                                          Color topColor,
                                          int leftStyle,
                                          Color leftColor,
                                          int bottomStyle,
                                          Color bottomColor,
                                          int rightStyle,
                                          Color rightColor,
                                          int horizentalStyle,
                                          Color horizentalColor,
                                          int verticalStyle,
                                          Color verticalColor) {

        final BorderStyle tmpStyle =
                new BorderStyle(topStyle,
                                topColor,
                                leftStyle,
                                leftColor,
                                bottomStyle,
                                bottomColor,
                                rightStyle,
                                rightColor,
                                horizentalStyle,
                                horizentalColor,
                                verticalStyle,
                                verticalColor);

        final BorderStyle borderStyle = BorderStyle.cachedBorderStyle.get(tmpStyle);

        if (borderStyle != null) {
            return borderStyle;
        }

        BorderStyle.cachedBorderStyle.put(tmpStyle, tmpStyle);

        return tmpStyle;
    }

    /**
     * 构造器
     */
    public BorderStyle() {}

    /**
     * 构造器
     * 
     * @param topStyle 上边框类型
     * @param topColor 上边框颜色
     * @param leftStyle 左边框类型
     * @param leftColor 左边框颜色
     * @param bottomStyle 下边框类型
     * @param bottomColor 下边框颜色
     * @param rightStyle 右边框类型
     * @param rightColor 右边框颜色
     */
    public BorderStyle(int topStyle,
                       Color topColor,
                       int leftStyle,
                       Color leftColor,
                       int bottomStyle,
                       Color bottomColor,
                       int rightStyle,
                       Color rightColor) {

        this.topStyle = topStyle;
        this.topColor = topColor;
        this.leftStyle = leftStyle;
        this.leftColor = leftColor;
        this.bottomStyle = bottomStyle;
        this.bottomColor = bottomColor;
        this.rightStyle = rightStyle;
        this.rightColor = rightColor;
    }

    /**
     * 构造器
     * 
     * @param topStyle 上边框类型
     * @param topColor 上边框颜色
     * @param leftStyle 左边框类型
     * @param leftColor 左边框颜色
     * @param bottomStyle 下边框类型
     * @param bottomColor 下边框颜色
     * @param rightStyle 右边框类型
     * @param rightColor 右边框颜色
     * @param horizentalStyle 水平线类型
     * @param horizentalColor 水平线颜色
     * @param verticalStyle 垂直线类型
     * @param verticalColor 垂直线颜色
     */
    private BorderStyle(int topStyle,
                        Color topColor,
                        int leftStyle,
                        Color leftColor,
                        int bottomStyle,
                        Color bottomColor,
                        int rightStyle,
                        Color rightColor,
                        int horizentalStyle,
                        Color horizentalColor,
                        int verticalStyle,
                        Color verticalColor) {
        this(topStyle, topColor, leftStyle, leftColor, bottomStyle, bottomColor, rightStyle, rightColor);

        this.horizentalStyle = horizentalStyle;
        this.horizentalColor = horizentalColor;
        this.verticalStyle = verticalStyle;
        this.verticalColor = verticalColor;
    }

    /**
     * 应用下边框颜色
     * 
     * @param bottomColor 下边框颜色
     * @return 单元格边框样式
     */
    public BorderStyle applyBottomColor(Color bottomColor) {
        return BorderStyle.getInstance(getTopStyle(),
                                       getTopColor(),
                                       getLeftStyle(),
                                       getLeftColor(),
                                       getBottomStyle(),
                                       bottomColor,
                                       getRightStyle(),
                                       getRightColor(),
                                       getHorizentalStyle(),
                                       getHorizentalColor(),
                                       getVerticalStyle(),
                                       getVerticalColor());
    }

    /**
     * 应用下边框类型
     * 
     * @param bottomStyle 下边框类型
     * @return 单元格边框样式
     */
    public BorderStyle applyBottomStyle(int bottomStyle) {
        return BorderStyle.getInstance(getTopStyle(),
                                       getTopColor(),
                                       getLeftStyle(),
                                       getLeftColor(),
                                       bottomStyle,
                                       getBottomColor(),
                                       getRightStyle(),
                                       getRightColor(),
                                       getHorizentalStyle(),
                                       getHorizentalColor(),
                                       getVerticalStyle(),
                                       getVerticalColor());
    }

    /**
     * 应用水平线颜色
     * 
     * @param horizentalColor 水平线颜色
     * @return 单元格边框样式
     */
    public BorderStyle applyHorizentalColor(Color horizentalColor) {
        return BorderStyle.getInstance(getTopStyle(),
                                       getTopColor(),
                                       getLeftStyle(),
                                       getLeftColor(),
                                       getBottomStyle(),
                                       getBottomColor(),
                                       getRightStyle(),
                                       getRightColor(),
                                       getHorizentalStyle(),
                                       horizentalColor,
                                       getVerticalStyle(),
                                       getVerticalColor());
    }

    /**
     * 应用水平线类型
     * 
     * @param horizentalStyle 水平线类型
     * @return 单元格边框样式
     */
    public BorderStyle applyHorizentalStyle(int horizentalStyle) {
        return BorderStyle.getInstance(getTopStyle(),
                                       getTopColor(),
                                       getLeftStyle(),
                                       getLeftColor(),
                                       getBottomStyle(),
                                       getBottomColor(),
                                       getRightStyle(),
                                       getRightColor(),
                                       horizentalStyle,
                                       getHorizentalColor(),
                                       getVerticalStyle(),
                                       getVerticalColor());
    }

    /**
     * 应用左边框颜色
     * 
     * @param leftColor 左边框颜色
     * @return 单元格边框样式
     */
    public BorderStyle applyLeftColor(Color leftColor) {
        return BorderStyle.getInstance(getTopStyle(),
                                       getTopColor(),
                                       getLeftStyle(),
                                       leftColor,
                                       getBottomStyle(),
                                       getBottomColor(),
                                       getRightStyle(),
                                       getRightColor(),
                                       getHorizentalStyle(),
                                       getHorizentalColor(),
                                       getVerticalStyle(),
                                       getVerticalColor());
    }

    /**
     * 应用左边框类型
     * 
     * @param leftStyle 左边框类型
     * @return 单元格边框样式
     */
    public BorderStyle applyLeftStyle(int leftStyle) {
        return BorderStyle.getInstance(getTopStyle(),
                                       getTopColor(),
                                       leftStyle,
                                       getLeftColor(),
                                       getBottomStyle(),
                                       getBottomColor(),
                                       getRightStyle(),
                                       getRightColor(),
                                       getHorizentalStyle(),
                                       getHorizentalColor(),
                                       getVerticalStyle(),
                                       getVerticalColor());
    }

    /**
     * 应用右边框颜色
     * 
     * @param rightColor 右边框颜色
     * @return 单元格边框样式
     */
    public BorderStyle applyRightColor(Color rightColor) {
        return BorderStyle.getInstance(getTopStyle(),
                                       getTopColor(),
                                       getLeftStyle(),
                                       getLeftColor(),
                                       getBottomStyle(),
                                       getBottomColor(),
                                       getRightStyle(),
                                       rightColor,
                                       getHorizentalStyle(),
                                       getHorizentalColor(),
                                       getVerticalStyle(),
                                       getVerticalColor());
    }

    /**
     * 应用右边框类型
     * 
     * @param rightStyle 右边框类型
     * @return 单元格边框样式
     */
    public BorderStyle applyRightStyle(int rightStyle) {
        return BorderStyle.getInstance(getTopStyle(),
                                       getTopColor(),
                                       getLeftStyle(),
                                       getLeftColor(),
                                       getBottomStyle(),
                                       getBottomColor(),
                                       rightStyle,
                                       getRightColor(),
                                       getHorizentalStyle(),
                                       getHorizentalColor(),
                                       getVerticalStyle(),
                                       getVerticalColor());
    }

    /**
     * 应用上边框颜色
     * 
     * @param topColor 上边框颜色
     * @return 单元格边框样式
     */
    public BorderStyle applyTopColor(Color topColor) {
        return BorderStyle.getInstance(getTopStyle(),
                                       topColor,
                                       getLeftStyle(),
                                       getLeftColor(),
                                       getBottomStyle(),
                                       getBottomColor(),
                                       getRightStyle(),
                                       getRightColor(),
                                       getHorizentalStyle(),
                                       getHorizentalColor(),
                                       getVerticalStyle(),
                                       getVerticalColor());
    }

    /**
     * 应用上边框类型
     * 
     * @param topStyle 上边框类型
     * @return 单元格边框样式
     */
    public BorderStyle applyTopStyle(int topStyle) {
        return BorderStyle.getInstance(topStyle,
                                       getTopColor(),
                                       getLeftStyle(),
                                       getLeftColor(),
                                       getBottomStyle(),
                                       getBottomColor(),
                                       getRightStyle(),
                                       getRightColor(),
                                       getHorizentalStyle(),
                                       getHorizentalColor(),
                                       getVerticalStyle(),
                                       getVerticalColor());
    }

    /**
     * 应用垂直线颜色
     * 
     * @param verticalColor 垂直线颜色
     * @return 单元格边框样式
     */
    public BorderStyle applyVerticalColor(Color verticalColor) {
        return BorderStyle.getInstance(getTopStyle(),
                                       getTopColor(),
                                       getLeftStyle(),
                                       getLeftColor(),
                                       getBottomStyle(),
                                       getBottomColor(),
                                       getRightStyle(),
                                       getRightColor(),
                                       getHorizentalStyle(),
                                       getHorizentalColor(),
                                       getVerticalStyle(),
                                       verticalColor);
    }

    /**
     * 应用垂直线类型
     * 
     * @param verticalStyle 垂直线类型
     * @return 单元格边框样式
     */
    public BorderStyle applyVerticalStyle(int verticalStyle) {
        return BorderStyle.getInstance(getTopStyle(),
                                       getTopColor(),
                                       getLeftStyle(),
                                       getLeftColor(),
                                       getBottomStyle(),
                                       getBottomColor(),
                                       getRightStyle(),
                                       getRightColor(),
                                       getHorizentalStyle(),
                                       getHorizentalColor(),
                                       verticalStyle,
                                       getVerticalColor());
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null) {
            return false;
        }
        if (getClass() != o.getClass()) {
            return false;
        }

        final BorderStyle border = (BorderStyle) o;

        return ((getTopStyle() == border.getTopStyle())
                && (getBottomStyle() == border.getBottomStyle())
                && (getLeftStyle() == border.getLeftStyle())
                && (getRightStyle() == border.getRightStyle())
                && (getTopColor().equals(border.getTopColor()))
                && (getBottomColor().equals(border.getBottomColor()))
                && (getLeftColor().equals(border.getLeftColor()))
                && (getRightColor().equals(border.getRightColor()))
                && (getHorizentalStyle() == border.getHorizentalStyle())
                && (getHorizentalColor().equals(border.getHorizentalColor()))
                && (getVerticalStyle() == border.getVerticalStyle()) && (getVerticalColor().equals(border.getVerticalColor())));
    }

    /**
     * 
     * @return 下边框颜色
     */
    public Color getBottomColor() {
        return bottomColor;
    }

    /**
     * 
     * @return 下边框类型
     */
    public int getBottomStyle() {
        return bottomStyle;
    }

    /**
     * 
     * @return 水平线颜色
     */
    public Color getHorizentalColor() {
        return horizentalColor;
    }

    /**
     * 
     * @return 水平线类型
     */
    public int getHorizentalStyle() {
        return horizentalStyle;
    }

    /**
     * 
     * @return 左边框颜色
     */
    public Color getLeftColor() {
        return leftColor;
    }

    /**
     * 
     * @return 左边框类型
     */
    public int getLeftStyle() {
        return leftStyle;
    }

    /**
     * 
     * @return 右边框颜色
     */
    public Color getRightColor() {
        return rightColor;
    }

    /**
     * 
     * @return 右边框类型
     */
    public int getRightStyle() {
        return rightStyle;
    }

    /**
     * 
     * @return 上边框颜色
     */
    public Color getTopColor() {
        return topColor;
    }

    /**
     * 
     * @return 上边框类型
     */
    public int getTopStyle() {
        return topStyle;
    }

    /**
     * 
     * @return 垂直线颜色
     */
    public Color getVerticalColor() {
        return verticalColor;
    }

    /**
     * 
     * @return 垂直线类型
     */
    public int getVerticalStyle() {
        return verticalStyle;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;

        result = prime * result + getTopStyle();
        result = prime * result + getTopColor().hashCode();
        result = prime * result + getLeftStyle();
        result = prime * result + getLeftColor().hashCode();
        result = prime * result + getBottomStyle();
        result = prime * result + getBottomColor().hashCode();
        result = prime * result + getRightStyle();
        result = prime * result + getRightColor().hashCode();
        result = prime * result + getHorizentalStyle();
        result = prime * result + getHorizentalColor().hashCode();
        result = prime * result + getVerticalStyle();
        result = prime * result + getVerticalColor().hashCode();

        return result;
    }

    public void setBottomColor(Color bottomColor) {
        this.bottomColor = bottomColor;
    }

    public void setBottomStyle(int bottomStyle) {
        this.bottomStyle = bottomStyle;
    }

    public void setHorizentalColor(Color horizentalColor) {
        this.horizentalColor = horizentalColor;
    }

    public void setHorizentalStyle(int horizentalStyle) {
        this.horizentalStyle = horizentalStyle;
    }

    public void setLeftColor(Color leftColor) {
        this.leftColor = leftColor;
    }

    public void setLeftStyle(int leftStyle) {
        this.leftStyle = leftStyle;
    }

    public void setRightColor(Color rightColor) {
        this.rightColor = rightColor;
    }

    public void setRightStyle(int rightStyle) {
        this.rightStyle = rightStyle;
    }

    public void setTopColor(Color topColor) {
        this.topColor = topColor;
    }

    public void setTopStyle(int topStyle) {
        this.topStyle = topStyle;
    }

    public void setVerticalColor(Color verticalColor) {
        this.verticalColor = verticalColor;
    }

    public void setVerticalStyle(int verticalStyle) {
        this.verticalStyle = verticalStyle;
    }

    @Override
    public String toString() {
        return "topStyle = "
               + getTopStyle()
               + ",topColor = "
               + getTopColor()
               + ",leftStyle = "
               + getLeftStyle()
               + ",leftColor = "
               + getLeftColor()
               + ",bottomStyle = "
               + getBottomStyle()
               + ",bottomColor = "
               + getBottomColor()
               + ",rightStyle = "
               + getRightStyle()
               + ",rightColor = "
               + getRightColor()
               + ",horizentalStyle = "
               + getHorizentalStyle()
               + ",horizentalColor = "
               + getHorizentalColor()
               + ",verticalStyle = "
               + getHorizentalStyle()
               + ",verticalColor = "
               + getVerticalColor();
    }
}
